
import { toRaw } from 'vue'

import type {
  TStateKey,
  TAnyObject,
  IModel
} from '../types/type'

import BaseObject from './base-object'
 

/**
 * 表单的model，加上 $reset 功能
 * @param fun 初始值，函数，方便实现重置的功能
 * @param id 标识，记录日志用
 */
export default class BaseModel<T extends TAnyObject> extends BaseObject<T> implements IModel<T> {
  #_value: () => T // 初始函数 
  constructor (
    fun: () => T,
    id: TStateKey = Symbol('_Model'),
  ) {
    if (typeof fun === 'function') {
      // 调用父类初始化，然后才会有this
      super(fun(), id)
      // 记录初始函数
      this.#_value = fun
    } else {
      super({} as T, id)
      this.#_value = () => { return {} as T}
      return
    }
  }

  /**
   * 恢复初始值，值支持浅层
   */
  $reset() {
    // 模板里面触发的事件，没有 this
    if (this) {
      const tmp = toRaw(this).#_value()
      this.$state = tmp
    } else {
      console.warn('在 template 里面使用的时候，请加上()，比如： foo.$reset()。')
    }
  }

  /**
   * 新 model 替换旧 model，delete 原有属性，set 新属性
   */
  set $set(value: TAnyObject) {
    // 删除原有属性
    Object.keys(this).forEach(key => {
      delete this[key as keyof this]
    })
    // 设置新属性
    Object.assign(this, value)
  }
}